""" S3D.IO package """
import os

def tryOpen(filename, mask, message):
    try:
        f = open(filename, mask)
        return f
    except IOError:
        print(message.format(**vars()))
        return None

def tryOpenRead(filename):
    return tryOpen(filename, "r", "Error: Failed to open file for reading: \"{filename}\"")

def tryOpenReadBin(filename):
    return tryOpen(filename, "rb", "Error: Failed to open file for reading: \"{filename}\"")

def tryOpenWrite(filename):
    return tryOpen(filename, "w", "Error: Failed to open file for writing: \"{filename}\"")

def tryOpenWriteBin(filename):
    return tryOpen(filename, "wb", "Error: Failed to open file for writing: \"{filename}\"")

def dir_name_ext(root, name_ext):
    name, ext = os.path.splitext(name_ext)
    return root, name, ext

def walk_files(path, ext=None, res_proc=os.path.join):
    if ext is None:
        for root, dirs, files in os.walk(path):
            for name in files:
                yield res_proc(root, name)
    elif isinstance(ext, str):
        for root, dirs, files in os.walk(path):
            for name in files:
                _, cur_ext = os.path.splitext(name)
                if cur_ext.lower() == ext:
                    yield res_proc(root, name)
    else:
        for root, dirs, files in os.walk(path):
            for name in files:
                filename = os.path.join(root, name)
                if ext(filename):
                    yield res_proc(root, name)
